/**
 * Copyright 2021 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef EXECUTE_GRAPH_SHAPE_H
#define EXECUTE_GRAPH_SHAPE_H
#include <array>
#include <vector>
#include "definitions.h"
namespace ge {
constexpr int64_t kUnknownDim = -1;
constexpr int64_t kUnknownDimNum = -2;
constexpr int64_t kUninitialized = -3;
using DimsType = std::array<int64_t, kDefaultRankLimit>;
using RangeType = std::array<std::pair<int64_t, int64_t>, kDefaultRankLimit>;
class Shape {
 public:
  int64_t GetDim(size_t index) const;
  int64_t &GetDim(size_t index);
  const DimsType &GetDims() const;
  std::vector<int64_t> GetDimsVec() const;
  Status SetDim(size_t index, int64_t dim_value);
  Status SetDims(const std::initializer_list<int64_t> &dims);
  size_t GetDimNum() const;
  void SetDimNum(size_t dim_num);
  bool IsScaler() const;
  // deprecated：概念不对，不推荐使用
  int64_t GetShapeSize() const;
  int64_t GetElementCount() const;
  // 低效接口，仅可以在异常分支使用
  std::string ToString() const;

  Shape() = default;
  Shape(const Shape &) = default;
  // 不明白场景是什么，不推荐使用，外层构造vector也是开销
  explicit Shape(const std::vector<int64_t> &dims);
  Shape(std::initializer_list<int64_t> dims);
  Shape &operator=(const Shape &) = default;
  Shape &operator=(Shape &&) = default;
  bool operator==(const Shape &other) const;
  bool operator!=(const Shape &other) const;
 private:
  size_t rank_{0};
  DimsType dims_;
};

class Range {
 public:
  size_t GetDimsCount() const;
  void SetDimNum(size_t dim_num);
  const std::pair<int64_t, int64_t> &GetDimRange(size_t index) const;
  std::pair<int64_t, int64_t> &GetDimRange(size_t index);
  void SetDimRange(size_t index, std::pair<int64_t, int64_t> dim_range);
 private:
  size_t rank_{0};
  RangeType range_;
};
}

#endif  //EXECUTE_GRAPH_SHAPE_H
